/*
 * Copyright 2013 Sigurd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.digiway.rapidbreeze.client.infrastructure.cnl;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import org.eclipse.jetty.server.Server;

/**
 *
 * @author Sigurd
 */
public class ClickAndLoadServer {

    private static final int CNL_PORT = 9666;
    private Server server;

    /**
     * Starts the CNL Server.
     *
     * @throws IllegalStateException if the port is already in use by another
     * application or if an error occured during startup of the server
     */
    public void start() {
        initServer();
        if (server.isStopped() || !server.isStarted()) {
            try {
                server.start();
            } catch (Exception ex) {
                throw new IllegalStateException("Error during startup of CNL server.", ex);
            }
        }

    }

    /**
     * Stops the server. Any active request will still be answered.
     *
     * @throws IllegalStateException if an error occurs during stopping the
     * server.
     */
    public void stop() {
        initServer();
        if (server.isRunning()) {
            try {
                server.stop();
            } catch (Exception ex) {
                throw new IllegalStateException("Error during stopping of CNL server.", ex);
            }
        }
    }

    private void initServer() {
        if (server == null) {
            if (!isPortAvailable()) {
                throw new IllegalStateException("Cannot open port:" + CNL_PORT + " for CNL communication. Port seems to be in use.");
            }
            InetSocketAddress address = InetSocketAddress.createUnresolved("localhost", CNL_PORT);
            server = new Server(address);
            server.setHandler(new ClickAndLoadHandler());
        }
    }

    /**
     * Checks if the CNL port is available. This might not be the case if the
     * local CNL Server is already runnning or another application is already
     * using the port (e.g. JDownloader)
     *
     * @return true if available
     */
    public boolean isPortAvailable() {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(CNL_PORT);
            ss.setReuseAddress(true);
            return true;
        } catch (IOException e) {
        } finally {
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    /* should not be thrown */
                }
            }
        }
        return false;
    }
}
